/* $RCSFile: CrmFieldLocalizer.ascx.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/CrmFieldLocalizer/CrmFieldLocalizer.ascx.cs $
 * $log$
 * Revision 20 2010/08/09 10:51:19  christian.surieux
 *   Added Log comment to all .aspx .ascx .master files
 * Revision 19 2010/08/09 09:43:48  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:24  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.Security;
using System.Web.Services.Protocols;

using AddonNice.UI;
using AddonNice.Design;
using AddonNice.UI.WebControls;
using AddonNice.Security;
using AddonNice.UI.DataTypes;
using AddonNice.Configuration;
using AddonNice.Configuration.Settings;
using AddonNice.Diagnostics;
using AddonNice.Helpers;
using AddonNice.Settings;
using AddonNice.Authentication;

using AddonNice.CRMWrapper;
using AddonNice.CRMWrapper.Design;

using Telerik.Web.UI;

using Trace2    =   System.Diagnostics.Trace;

namespace AddonNice.PageModules.CrmFieldLocalizer 
{

 	#region Local TraceSwitch 
	public class CrmFieldLocTrace : ADNTraceSwitch
	{
		static public ADNTraceSwitch	Sw	            =	new ADNTraceSwitch("CrmFieldLocTrace","Special Trace Switch for CrmFieldLocalizer");
	}
	#endregion Local TraceSwitch 

    #region const strings
    public class LStr
    {
		public const string CrmFieldLocalizerEntity  	        =	"MODULE_SETTINGS_FIELD_LOC_ENTITY";
		public const string CrmFieldLocalizerFields  	        =	"MODULE_SETTINGS_FIELD_LOC_FIELDS";
        public const string CrmFieldLocalizerNbTabs             =	"MODULE_SETTINGS_FIELD_LOC_NBTABS";
        public const string CrmFieldLocalizerTabsOrientation    =	"MODULE_SETTINGS_FIELD_LOC_TABSORIENTATION";
        public const string GoogleTranslate                     =	"MODULE_SETTINGS_FIELD_LOC_GOGGLETRANSLATE";
        public const string CrmFieldLocalizerMemoLen            =	"MODULE_SETTINGS_FIELD_LOC_MEMOLEN";
        public const string CrmFieldLocalizerTextLen            =	"MODULE_SETTINGS_FIELD_LOC_TEXTLEN";
        public const string CrmFieldLocalizerMemoSize           =	"MODULE_SETTINGS_FIELD_LOC_MEMOSIZE";
        public const string CrmFieldLocalizerTextSize           =	"MODULE_SETTINGS_FIELD_LOC_TEXTSIZE";
        public const string CrmFieldLocalizerMemoHTML           =	"MODULE_SETTINGS_FIELD_LOC_MEMOEDITOR";
            
    }
    #endregion const strings
    
	/// <summary>
    /// Initializer class for CreateCrmEntity 
    /// </summary>
    public class CrmFieldLocalizerSI : PortalCRMModuleControlSI
    {
        FieldLocalizerDB fDB                                    =   new FieldLocalizerDB();

        ArrayList _AllEntities  =   null;
        ArrayList GetAllEntities()
        {
            if (_AllEntities == null)
            {
                _AllEntities    =   MetadataCache.GetAllEntities(Wrapper,true);
            }
            return _AllEntities;
        }
        
        /// <summary>
        /// Get the Entity Config to build the attributes table for an entity
        /// </summary>
        EntityConfig _TConfig   =   null;
        string _entityName      =   string.Empty; //small caching for columns
        public EntityConfig GetEntityConfig(string entityName)
        {
            if (_TConfig == null || 
                (_TConfig.entityFlags != EntityInternalItems.All) || 
                ( !_TConfig.isAdmin ) || 
                (_entityName != entityName) )
            {
                _TConfig        =   new EntityConfig(Wrapper,entityName);
                _entityName     =   entityName;
                if ( CrmFieldLocTrace.Sw.TraceVerbose )
                    Trace2.WriteLine(
                    string.Format("[V]CrmFieldLocalizer GetEntityConfig created entityName: {0}, vflag: [{1}], isAdmin: {2}, DisplayMask: [{3}] ",
                    new object[] {entityName,_TConfig.entityFlags, true, _TConfig.DisplayMask }),CrmFieldLocTrace.Sw.Info);
            }
            return _TConfig;
        }

        public CrmFieldLocalizerSI(ModuleSettingsDictionary bSettings,ISettingsOwner pm) : base()
        {
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizerSI Ctor BEG.",ModuleTraceSwitch.Sw.Info);
            InitSettings(bSettings,pm);
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizerSI Ctor END.",ModuleTraceSwitch.Sw.Info);
        }
 
        public override void InitSettings(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
        {             
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizerSI InitSettings BEG.",ModuleTraceSwitch.Sw.Info);
            
            base.InitSettings(bSettings,pm);
            string extgrp                               =   pm.ExtendedResourcesGroup;
            const string extgrp1                        =   "CRMFIELDLOCALIZER1";
            

            SettingItemSpecial CrmFieldLocalizerMemoHTML=   new SettingItemSpecial(LStr.CrmFieldLocalizerMemoHTML,new BooleanDataType());
			CrmFieldLocalizerMemoHTML.Order			    =	10;
            CrmFieldLocalizerMemoHTML.ExtendedGroupName =   extgrp;
            CrmFieldLocalizerMemoHTML.Group             =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmFieldLocalizerMemoHTML.Value			    =	StStr.strTrue; // default value
			CrmFieldLocalizerMemoHTML.Description		=	"Check to use Addon Nice html editor for memo fields";
            CrmFieldLocalizerMemoHTML.EnglishName		=	"Html editor for memo fields";
			bSettings.AddSetting(CrmFieldLocalizerMemoHTML);
            
            SettingItemSpecial CrmGoogleTranslate       =   new SettingItemSpecial(LStr.GoogleTranslate,new BooleanDataType());
			CrmGoogleTranslate.Order			        =	15;
            CrmGoogleTranslate.ExtendedGroupName        =   extgrp;
            CrmGoogleTranslate.Group                    =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmGoogleTranslate.Value			        =	portalSettings.CustomSettings[StStr.SiteSettingsGoogleTranslate].Value;
			CrmGoogleTranslate.Description		        =	"Uncheck this setting if your client has no internet access.";
            CrmGoogleTranslate.EnglishName		        =	"Use Goggle Translation";
			bSettings.AddSetting(CrmGoogleTranslate);

            SettingItemSpecial CrmFieldLocalizerNbTabs  =   new SettingItemSpecial(LStr.CrmFieldLocalizerNbTabs,new IntegerDataType());
			CrmFieldLocalizerNbTabs.Order			    =	20;
            CrmFieldLocalizerNbTabs.ExtendedGroupName   =   extgrp;
            CrmFieldLocalizerNbTabs.Group               =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmFieldLocalizerNbTabs.Value			    =	"1"; // default value
			CrmFieldLocalizerNbTabs.Description		    =	"Fields will be sparsed between tabs (0 or 1 means no tabs), memo fields will take a full tab.";
            CrmFieldLocalizerNbTabs.EnglishName		    =	"Display Tabs";
			bSettings.AddSetting(CrmFieldLocalizerNbTabs);

            SettingItemSpecial HorizTabs                =   new SettingItemSpecial(LStr.CrmFieldLocalizerTabsOrientation,new ListDataType(typeof(TabStripOrientation)));
			HorizTabs.Order			                    =	30;
            HorizTabs.ExtendedGroupName                 =   extgrp;
            HorizTabs.Group                             =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            HorizTabs.Value			                    =	TabStripOrientation.HorizontalTop.ToString(); // default value
			HorizTabs.Description		                =	"If you ask for Tabs, select their position";
            HorizTabs.EnglishName		                =	"Tabs Orientation";
			bSettings.AddSetting(HorizTabs);

            SettingItemSpecial CrmFieldLocalizerMemoLen =   new SettingItemSpecial(LStr.CrmFieldLocalizerMemoLen,new IntegerDataType());
			CrmFieldLocalizerMemoLen.Order			    =	40;
            CrmFieldLocalizerMemoLen.ExtendedGroupName  =   extgrp;
            CrmFieldLocalizerMemoLen.Group              =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmFieldLocalizerMemoLen.Value			    =	"0"; // default value
			CrmFieldLocalizerMemoLen.Description		=	"Value to limit the Memo field length, zero means no limit.";
            CrmFieldLocalizerMemoLen.EnglishName		=	"Memo field length";
			bSettings.AddSetting(CrmFieldLocalizerMemoLen);

            SettingItemSpecial CrmFieldLocalizerMemoSize =   new SettingItemSpecial(LStr.CrmFieldLocalizerMemoSize,new UnitDataType());
			CrmFieldLocalizerMemoSize.Order			    =	50;
            CrmFieldLocalizerMemoSize.ExtendedGroupName =   extgrp;
            CrmFieldLocalizerMemoSize.Group             =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmFieldLocalizerMemoSize.Value			    =	"800px"; // default value
			CrmFieldLocalizerMemoSize.Description		=	"Display width in pixel for Memo fields";
            CrmFieldLocalizerMemoSize.EnglishName		=	"Memo field display width";
			bSettings.AddSetting(CrmFieldLocalizerMemoSize);

            SettingItemSpecial CrmFieldLocalizerTextLen =   new SettingItemSpecial(LStr.CrmFieldLocalizerTextLen,new IntegerDataType());
			CrmFieldLocalizerTextLen.Order			    =	60;
            CrmFieldLocalizerTextLen.ExtendedGroupName  =   extgrp;
            CrmFieldLocalizerTextLen.Group              =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmFieldLocalizerTextLen.Value			    =	"0"; // default value
			CrmFieldLocalizerTextLen.Description		=	"Value to limit the Text field length, zero means no limit.";
            CrmFieldLocalizerTextLen.EnglishName		=	"Text field length";
			bSettings.AddSetting(CrmFieldLocalizerTextLen);

            SettingItemSpecial CrmFieldLocalizerTextSize =   new SettingItemSpecial(LStr.CrmFieldLocalizerTextSize,new UnitDataType());
			CrmFieldLocalizerTextSize.Order			    =	70;
            CrmFieldLocalizerTextSize.ExtendedGroupName =   extgrp;
            CrmFieldLocalizerTextSize.Group             =   SettingItemGroup.MODULE_SPECIAL_SETTINGS;
            CrmFieldLocalizerTextSize.Value			    =	"400px"; // default value
			CrmFieldLocalizerTextSize.Description		=	"Display width in pixel for Text fields";
            CrmFieldLocalizerTextSize.EnglishName		=	"Text field display width";
			bSettings.AddSetting(CrmFieldLocalizerTextSize);


            ArrayList are                               =   GetAllEntities();
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Ctor Nb entities: {0}",are.Count),CrmFieldLocTrace.Sw.Info);
            CustomListDataType ECombo                   =   new CustomListDataType(are, "displayName", "entityName");
            ECombo.SortOrder                            =   RadComboBoxSort.Ascending;
            SettingItemSpecial CrmFieldLocalizerEntity  =   new SettingItemSpecial(LStr.CrmFieldLocalizerEntity,ECombo);
			CrmFieldLocalizerEntity.Required			=	true;
			CrmFieldLocalizerEntity.Order			    =	110;
            CrmFieldLocalizerEntity.ExtendedGroupName   =   extgrp1;
            CrmFieldLocalizerEntity.Group               =   SettingItemGroup.MODULE_SPECIAL_SETTINGS1;
            CrmFieldLocalizerEntity.Value			    =	CrmStr.account; // default value
			CrmFieldLocalizerEntity.Description		    =	"Select an entity to display";
            CrmFieldLocalizerEntity.EnglishName		    =	"Entity";
			bSettings.AddSetting(CrmFieldLocalizerEntity);
            
            DataTable tb                                =   CRMLocalizer.CreateAttributesTable();

            EntityConfig econf                          =   GetEntityConfig(CrmStr.account);
            InternalDisplayMasks validFlag              =   InternalDisplayMasks.PrimaryName|InternalDisplayMasks.RequiredForGrid|
                                    InternalDisplayMasks.RequiredForGrid |InternalDisplayMasks.RequiredForForm|
                                    InternalDisplayMasks.ValidForForm|InternalDisplayMasks.ValidForAdvancedFind;
            // Take only text attribtes
            econf.InsertAttributesInTable(tb,validFlag,true,true,false,AttributeInternalType.String);
            econf.InsertAttributesInTable(tb,validFlag,true,true,false,AttributeInternalType.Memo);

            CRMFieldDescList SelVals                    =   new CRMLocalizer(CrmStr.account).Vals;
            StringBuilder sb                            =   new StringBuilder();
            foreach ( CRMFieldDescListKey key in SelVals.Keys )
            {
                sb.AppendFormat("{0};",key.Fieldname);
            }
            string SelVal                               =   sb.ToString();
            DataView    dv                              =   tb.DefaultView;
            dv.Sort                                     =   CrmStr.strConfDisplayName;
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Ctor SelVal: {0}",SelVal),CrmFieldLocTrace.Sw.Info);
            SelListBoxDataType SelTree                  =   new SelListBoxDataType(dv,CrmStr.strConfDisplayName,CrmStr.strConfSchemaName);
            SelTree.ListBoxHeight                       =   new Unit("400px");
            SettingItemSpecial CrmFieldLocalizerFields  =   new SettingItemSpecial(LStr.CrmFieldLocalizerFields,SelTree);
			CrmFieldLocalizerFields.Required			=	false;
			CrmFieldLocalizerFields.Order			    =	120;
            CrmFieldLocalizerFields.Value               =   SelVal;
			CrmFieldLocalizerFields.ExtendedGroupName   =   extgrp1;
            CrmFieldLocalizerFields.Group               =   SettingItemGroup.MODULE_SPECIAL_SETTINGS1;
			CrmFieldLocalizerFields.Description		    =	"Select fields to display";
            CrmFieldLocalizerFields.EnglishName		    =	"Fields";
            CrmFieldLocalizerFields.AddDependency(CrmFieldLocalizerEntity,new SettingItemsEventHandler(HandleEntityChange));
            // To handle save event and update FieldLocalizer desc table
            CrmFieldLocalizerFields.SettingItemsEvent   +=  new SettingItemsEventHandler(CrmFieldLocalizerFields_SettingItemsEvent);
			bSettings.AddSetting(CrmFieldLocalizerFields);
        }

    
        #region SettingsItems Handlers

        /// <summary>
        /// Called from settingsItems to handle a change in entity name
        /// </summary>
        void HandleEntityChange(object sender, SettingItemsEventArgs ev)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer HandleEntityChange BEG sender: {0}, EventType: {1}.",((SettingItem)sender).EnglishName,ev.EventType),CrmFieldLocTrace.Sw.Info);
            if ( ev.EventType != SettingItemsEventType.ParentLoaded 
                && ev.EventType != SettingItemsEventType.ParentChanged 
                && ev.EventType != SettingItemsEventType.ParentRebound )
            {
                if ( CrmFieldLocTrace.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer HandleEntityChange  DISCARDED sender: {0}, EventType: {1}, (ev.dataTypeEventArg == null): {2}.", ((SettingItem)sender).EnglishName, ev.EventType,ev.dataTypeEventArg == null ),CrmFieldLocTrace.Sw.Info);
                return;
            }
            
            string entityName                       =   Owner.Settings[LStr.CrmFieldLocalizerEntity].Value;
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer HandleEntityChange entityName: '{0}'",entityName),CrmFieldLocTrace.Sw.Info);
            DataTable tb                            =   CRMLocalizer.CreateAttributesTable();
            // reset GetEntityConfig to force reading new entityname
            EntityConfig econf                      =   GetEntityConfig(entityName);
            InternalDisplayMasks validFlag          =   InternalDisplayMasks.None | InternalDisplayMasks.RequiredForGrid |
                        InternalDisplayMasks.ValidForGrid | InternalDisplayMasks.RequiredForForm |
                        InternalDisplayMasks.ValidForForm | InternalDisplayMasks.ValidForAdvancedFind;
            econf.InsertAttributesInTable(tb,validFlag,true,true,false,AttributeInternalType.String);
            econf.InsertAttributesInTable(tb,validFlag,true,true,false,AttributeInternalType.Memo);
            CRMFieldDescList SelVals                =   new CRMLocalizer(entityName).Vals;
            StringBuilder sb                        =   new StringBuilder();
            foreach ( CRMFieldDescListKey key in SelVals.Keys )
            {
                sb.AppendFormat("{0};",key.Fieldname);
            }
            string SelVal                           =   sb.ToString();
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer HandleEntityChange SelVal: {0}",SelVal),CrmFieldLocTrace.Sw.Info);
            // we select by default only needed one
            DataView    dv                          =   tb.DefaultView;
            dv.Sort                                 =   CrmStr.strConfDisplayName;
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer HandleEntityChange installing fields for entityName: {0}, SelVal: {1}.",entityName,SelVal),CrmFieldLocTrace.Sw.Info);
            SettingItem CrmFieldLocalizerFields     =   Owner.Settings[LStr.CrmFieldLocalizerFields];
            CrmFieldLocalizerFields.DataType.ResetDataSource(dv,SelVal);
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer HandleEntityChange END entityName: {0}.",entityName),CrmFieldLocTrace.Sw.Info);
        }

        /// <summary>
        /// We must take care to read/update the FieldLocalizerDesc table on read and save setting value
        /// </summary>
        void CrmFieldLocalizerFields_SettingItemsEvent(object sender,SettingItemsEventArgs e)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent BEG EventType: {0}.",e.EventType),CrmFieldLocTrace.Sw.Info);
            if ( ( e.EventType != SettingItemsEventType.Saved ) &&
                (e.EventType != SettingItemsEventType.Loaded))
                return;
            // TBD  database value for this setting could be unsynch with values in CrmLocalizer, must be checked and resetted
            if ( e.EventType == SettingItemsEventType.Loaded )
            {
                if ( CrmFieldLocTrace.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent Data: {0}.",e.Data.ToString()),CrmFieldLocTrace.Sw.Info);
                return;
            }
            /// Triggered after settingItem has been saved to DB
            /// We must take care to update the FieldLocalizerDesc table
            string entityName                       =   Owner.Settings[LStr.CrmFieldLocalizerEntity].Value;
            string newval                           =   (string)e.Data;
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent entityName: {0}, newval: {1}.",entityName,newval),CrmFieldLocTrace.Sw.Info);
            EntityConfig conf                       =   GetEntityConfig(entityName);

            try
            {
                CRMFieldDescList OldVals            =   new CRMLocalizer(entityName).Vals;
                string[] newValTb                   =   newval.Split(new char[]{';'},StringSplitOptions.RemoveEmptyEntries);
                foreach ( string fldName in newValTb )
                {
                    CRMFieldDescListKey key         =   new CRMFieldDescListKey(Owner.PortalID,entityName,fldName);
                    bool exists                     =   OldVals.ContainsKey(key);
                    if ( CrmFieldLocTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent entityName: {0}, fldName: {1}, exists: {2}.",
                            entityName,newval,exists),CrmFieldLocTrace.Sw.Info);
                    if ( !exists )
                    {
                        InternalAttributeMetadata att   =   conf[fldName];
                        int attType                     =   Wrapper.Util.ExtractAttributeFieldAsInt(att,InternalAttributeFields.AttributeType);
                        int Flags                       =   Wrapper.Util.ExtractAttributeFieldAsInt(att,InternalAttributeFields.DisplayMask);
                        // To check: where is att length ?
                        int Length                      =   ( attType == (int)AttributeInternalType.Memo ) ? Owner.Settings[LStr.CrmFieldLocalizerMemoLen].ToInt() : Owner.Settings[LStr.CrmFieldLocalizerTextLen].ToInt();
                        int DSize                       =   0;
                        Unit USize                      =   ( attType == (int)AttributeInternalType.Memo ) ? Owner.Settings[LStr.CrmFieldLocalizerMemoSize].ToUnit() : Owner.Settings[LStr.CrmFieldLocalizerTextSize].ToUnit();
                        if ( !USize.IsEmpty && (USize.Type == UnitType.Pixel ) )
                            DSize                       =   (int)USize.Value;
                        if ( CrmFieldLocTrace.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent adding Key: {0}, attType: {1}."
                                ,fldName,(AttributeInternalType)attType),CrmFieldLocTrace.Sw.Info);
                        fDB.UpdateFieldLocalizerDesc(0,Owner.PortalID,entityName,fldName,attType,Flags,Length,DSize);
                        CRMLocalizer.ClearCache(Owner.PortalID,entityName);
                    }
                    else
                    {
                        OldVals.Remove(key);
                        CRMLocalizer.ClearCache(Owner.PortalID,key.TypeName);
                    }
                }
                // delete the suppressed values
                foreach ( CRMFieldDescListKey key in OldVals.Keys )
                {
                    if ( CrmFieldLocTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent deleting Key: {0}.",key.Fieldname),CrmFieldLocTrace.Sw.Info);
                    fDB.DeleteFieldLocalizerDesc(OldVals[key].FieldId);
                }
            }
            catch (Exception ex)
            {
                if ( ModuleTraceSwitch.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent ex: {0}",ex),ModuleTraceSwitch.Sw.Info);
                throw;
            }
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer CrmFieldLocalizerFields_SettingItemsEvent END.",CrmFieldLocTrace.Sw.Info);
        }

        #endregion SettingsItems Handlers
    }

    
    /// <summary>
    ///	CrmFieldLocalizer display prospects in a RadGrid.
    /// </summary>
	public partial class CrmFieldLocalizer : PortalCRMModuleControl
    {
        /// <summary>
        /// No entity needed here
        /// </summary>
        public override bool NeedAttachedEntity
        {
            get
            {
                return false;
            }
        }

 		#region General implementation

        /// <summary>
		/// AddonNice module key
		/// </summary>
		public override Guid GuidID
        {
            get
            {
               return new Guid(StStr.CrmFieldLocalizerGuid);
            }
        }
		#endregion General implementation

        #region Local Properties


        SortedList<CRMFieldDescListKey,CRMLocFieldDesc> Vals    =   new SortedList<CRMFieldDescListKey,CRMLocFieldDesc>();
        List<Control> StripMultiPages                           =   new List<Control>();
        SortedList<string,Control> EditControls                 =   new SortedList<string,Control>();
        SortedList<string,RadSpell> SpellCheckers               =   new SortedList<string,RadSpell>();
        FieldLocalizerDB fDB                                    =   new FieldLocalizerDB();
        DynEntity currentDyn                                    =   null;

        
        TabStripAlign  _Align   =   TabStripAlign.Left;
        
        /// <summary>
        /// Allows to transfer to RadTabStrip this parameter: center, justify, left, right
        /// Default left
        /// </summary>
        public TabStripAlign Align
        {
            get
            {
                return _Align;
            }
            set
            {
                _Align  = value;
            }
        }

        /// <summary>
        /// Allows to transfer to RadTabStrip this parameter: HorizontalTop, HorizontalBottom,VerticalLeft,VerticalRight
        /// Default HorizontalTop
        /// </summary>
        public TabStripOrientation Orientation 
        {
            get
            {
                string or   =   Settings[LStr.CrmFieldLocalizerTabsOrientation].Value;
                switch ( or )
                {
                    default:
                    case "HorizontalTop":
                    return TabStripOrientation.HorizontalTop;
                    case "HorizontalBottom":
                    return TabStripOrientation.HorizontalBottom;
                    case "VerticalLeft":
                    return TabStripOrientation.VerticalLeft;
                    case "VerticalRight":
                    return TabStripOrientation.VerticalRight;
                }
            }
        }

        bool GoogleTranslate
        {
            get
            {
                return Settings[LStr.GoogleTranslate].ToBool()&& portalSettings.CustomSettings[StStr.SiteSettingsGoogleTranslate].ToBool();
            }
        }

        /// <summary>
        /// TabStrip is vertical ? set according Orientation parameter
        /// </summary>
        public bool IsVertical
        {
            get
            {
                return (Orientation == TabStripOrientation.VerticalLeft ||
                            Orientation == TabStripOrientation.VerticalRight );
            }
        }

        bool NoTabs
        {
            get
            {
                int nbTabs      =   Settings[LStr.CrmFieldLocalizerNbTabs].ToInt();
                return ( nbTabs <= 0 );
            }
        }



        ArrayList _AllEntities  =   null;
        ArrayList GetAllEntities()
        {
            if (_AllEntities == null)
            {
                _AllEntities    =   MetadataCache.GetAllEntities(Wrapper,true);
            }
            return _AllEntities;
        }
        
        /// <summary>
        /// Get the Entity Config to build the attributes table for an entity
        /// </summary>
        EntityConfig _TConfig   =   null;
        string _entityName      =   string.Empty; //small caching for columns
        public EntityConfig GetEntityConfig(string entityName)
        {
            if (_TConfig == null || 
                (_TConfig.entityFlags != EntityInternalItems.All) || 
                ( !_TConfig.isAdmin ) || 
                (_entityName != entityName) )
            {
                _TConfig        =   new EntityConfig(Wrapper,entityName);
                _entityName     =   entityName;
                if ( CrmFieldLocTrace.Sw.TraceVerbose )
                    Trace2.WriteLine(
                    string.Format("[V]CrmFieldLocalizer GetEntityConfig created entityName: {0}, vflag: [{1}], isAdmin: {2}, DisplayMask: [{3}] ",
                    new object[] {entityName,_TConfig.entityFlags, true, _TConfig.DisplayMask }),CrmFieldLocTrace.Sw.Info);
            }
            return _TConfig;
        }

        #endregion local Properties

        #region Ctor and Initializer

        /// <summary>
        /// Ctor allows settings to select an entity and its fields to localize
        /// </summary>
        public CrmFieldLocalizer()
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmFieldLocalizer Ctor BEG",(CrmFieldLocTrace.Sw.TraceVerbose ) ? CrmFieldLocTrace.Sw.Info :ModuleTraceSwitch.Sw.Info);
		

            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine("[V]CrmFieldLocalizer Ctor END",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
        }

        public override string ExtendedResourcesGroup 
		{
            get
            {
                const string extgrp                         =   "CRMFIELDLOCALIZER";
                 return extgrp;
            }
		}

        public override void InitPortalModuleControl(ModuleSettingsDictionary bSettings)
        {
            PortalModuleInitializer =   new CrmFieldLocalizerSI(bSettings,this);
        }

        #endregion Ctor

  
        protected void Page_Load(object sender, EventArgs e)
        {
           if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
               Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Page_Load BEG IsPostBack: {0}, IsInAsyncPostBack: {1}",IsPostBack,IsInAsyncPostBack),( CrmFieldLocTrace.Sw.TraceVerbose ) ? CrmFieldLocTrace.Sw.Info :ModuleTraceSwitch.Sw.Info);
           
            // Add Reset Btn in AjaxManager targeting all edit controls or tabstrip/multipages if exist
           if ( NoTabs )
           {
               if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                   Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Page_Load EditControls.Count: {0}.",EditControls.Count),( CrmFieldLocTrace.Sw.TraceVerbose ) ? CrmFieldLocTrace.Sw.Info :ModuleTraceSwitch.Sw.Info);
               foreach ( Control c in EditControls.Values )
               {
                   AddAjaxSetting(ResetBtn,c);
                   AddAjaxSetting(LangChooser1,c);
               }
           }
           else
           {
               if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                   Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Page_Load StripMultiPages.Count: {0}.",StripMultiPages.Count),( CrmFieldLocTrace.Sw.TraceVerbose ) ? CrmFieldLocTrace.Sw.Info :ModuleTraceSwitch.Sw.Info);
               foreach ( Control c in StripMultiPages )
               {
                   AddAjaxSetting(ResetBtn,c);
                   AddAjaxSetting(LangChooser1,c);
               }
           }

           if ( !IsPostBack )
           {
                string[] SupportedLanguages      =   PortalSettings.SpellCheckerCultures;
                CultureInfo curCult              =   portalSettings.PortalContentLanguage;
                string currentLang               =   portalSettings.PortalContentLanguage.TwoLetterISOLanguageName;
                string selectedLang              =   string.Empty;
                foreach(string dicLang in SupportedLanguages)
                {
                    if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Page_Load currentLang: {0}, dicLang: {1}.",currentLang,dicLang),(CrmFieldLocTrace.Sw.TraceVerbose)? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
                    if ( currentLang == dicLang )
                    {
                        selectedLang             =   dicLang;
                        break;
                    }
                }
                if ( selectedLang == string.Empty )
                   foreach(string dicLang in SupportedLanguages)
                   {
                       CultureInfo cult         =   new CultureInfo(dicLang);
                       if ( cult.Parent == curCult )
                       {
                           selectedLang         =   dicLang;
                            break;
                       }
                   }
                if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Page_Load selectedLang: '{0}'",selectedLang),(CrmFieldLocTrace.Sw.TraceVerbose)? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);

                foreach(Control c in EditControls.Values)
                {
                   if ( c is RadEditor )
                   {
                        RadEditor e1                    =   (RadEditor)c;
                        e1.EnsureToolsFileLoaded();
                        foreach(string dicLang in SupportedLanguages)
                            e1.Languages.Add(new SpellCheckerLanguage(dicLang,new CultureInfo(dicLang).DisplayName));
                        e1.Language                     =   selectedLang;
                       if ( GoogleTranslate )
                       {
                           e1.OnClientCommandExecuting  =   "OnClientCommandExecuting";
                           // Add and fill the translate editor tool 
                           EditorDropDown ddn           =   new EditorDropDown("TranslateTool");
                           ddn.Text                     =   LocalizeHelper.Localize("EDITOR_TRANSLATE","Translate");
                           ddn.Width                    =   new Unit("130px");
                           e1.Tools[0].Tools.Insert(0,ddn);  
                           foreach(string dicLang in SupportedLanguages)
                           {
                               EditorDropDownItem it    =   new EditorDropDownItem(new CultureInfo(dicLang).DisplayName,dicLang.Substring(0,2));
                               ddn.Items.Add(it);
                           }
                        }
                   }
                   else
                   {
                       RadSpell sp                  =   SpellCheckers[c.ClientID];
                       sp.DictionaryLanguage        =   selectedLang;
                       sp.SupportedLanguages        =   SupportedLanguages;
                   }
                }
           }
           if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
               Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer Page_Load END IsPostBack: {0}",IsPostBack),(CrmFieldLocTrace.Sw.TraceVerbose)? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
         }

        #region Main methods


        bool CreateRow(CRMLocFieldDesc desc,string fldName,Table tb,List<RadEditor> EdLst,bool NoTabs)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateRow BEG Fieldname: '{0}'", desc.Fieldname),CrmFieldLocTrace.Sw.Info);
            bool isEditor                       =   false;
            TableRow rw                         =   new TableRow();
            TableCell c1                        =   new TableCell();
            c1.CssClass                         =   "FieldLocCellLabel";
            Label   lb                          =   new Label();
            lb.ID                               =   string.Format("lbl_{0}",fldName);
            lb.Text                             =   desc.DisplayName;
            lb.CssClass                         =   "FieldLocLabel";
            c1.Controls.Add(lb);
            TableCell c2                        =   new TableCell();
            c2.CssClass                         =   "FieldLocCellValue";
            int TextLen                         =   desc.FieldLenght;
            int memoLen                         =   desc.FieldLenght;
            if ( memoLen == 0 )
            {
                memoLen                         =   Settings[LStr.CrmFieldLocalizerMemoLen].ToInt();
                TextLen                         =   Settings[LStr.CrmFieldLocalizerTextLen].ToInt();
            }
            int memoSz                          =   desc.DisplaySize;
            Unit TextWidth                      =   Settings[LStr.CrmFieldLocalizerTextSize].ToUnit();
            Unit memoWidth                      =   Settings[LStr.CrmFieldLocalizerMemoSize].ToUnit();
            if ( memoSz > 0 )
            {
                memoWidth                       =   new Unit(memoSz, UnitType.Pixel);
                TextWidth                       =   new Unit(memoSz, UnitType.Pixel);
            }
            Control c                           =   null;
            bool oneCol                         =   false;
            string CtlID                        =   string.Format("ctl_{0}",fldName);

            switch ( desc.FieldType )
            {
                case AttributeInternalType.Memo:
                // Editor take full row length
                c1.ColumnSpan                       =   2;
                // no label with tabs as the tab name contains label
                if ( !NoTabs )
                {
                    rw.Cells.Add(c1);
                    tb.Rows.Add(rw);
                }
                rw                                  =   new TableRow();
                c1                                  =   c2;
                c1.ColumnSpan                       =   2;
                oneCol                              =   true;
                if ( Settings[LStr.CrmFieldLocalizerMemoHTML].ToBool() )
                {
                    isEditor                        =   true;
                    RadEditor e1                    =   new RadEditor();
                    e1.ID                           =   string.Format("RadEdt{0}_{1}",ID,fldName);
                    EdLst.Add(e1);
                    e1.ToolbarMode                  =    EditorToolbarMode.ShowOnFocus;
                    e1.Content                      =   desc.LongVal;
                    e1.Width                        =   memoWidth;
                    c                               =   e1;
                    //c1.                           =   memoLen;
                    //e1.AutoResizeHeight           =   false;
                    string[] folderPath             =   new string[] {portalSettings.DefaultImageVirtualPath};
                    e1.ImageManager.ViewPaths       =   folderPath;
                    e1.ImageManager.UploadPaths     =   folderPath;
                    e1.ImageManager.DeletePaths     =   folderPath;
                    
                    folderPath                      =   new string[] {portalSettings.DefaultMediaVirtualPath};
                    e1.MediaManager.ViewPaths       =   folderPath;
                    e1.MediaManager.UploadPaths     =   folderPath;
                    e1.MediaManager.DeletePaths     =   folderPath;

                    folderPath                      =   new string[] {portalSettings.DefaultFlashVirtualPath};
                    e1.FlashManager.ViewPaths       =   folderPath;
                    e1.FlashManager.UploadPaths     =   folderPath;
                    e1.FlashManager.DeletePaths     =   folderPath;

                    folderPath                      =   new string[] {portalSettings.DefaultSilverlightVirtualPath};
                    e1.SilverlightManager.ViewPaths     =   folderPath;
                    e1.SilverlightManager.UploadPaths   =   folderPath;
                    e1.SilverlightManager.DeletePaths   =   folderPath;
                    
                    folderPath                      =   new string[] {portalSettings.DefaultDocumentVirtualPath};
                    e1.DocumentManager.ViewPaths    =   folderPath;
                    e1.DocumentManager.UploadPaths  =   folderPath;
                    e1.DocumentManager.DeletePaths  =   folderPath;

                    folderPath                      =   new string[] {portalSettings.DefaultTemplateVirtualPath};
                    e1.TemplateManager.ViewPaths    =   folderPath;
                    e1.TemplateManager.UploadPaths  =   folderPath;
                    e1.TemplateManager.DeletePaths  =   folderPath;
                }
                else
                {
                    RadTextBox e                    =   new RadTextBox();
                    e.Text                          =   desc.LongVal;
                    e.Width                         =   memoWidth;
                    if ( memoLen > 0 )
                        e.MaxLength                 =   memoLen;
                    c                               =   e;
                }
                break;
                
                default: // TBC
                case AttributeInternalType.String:
                c                                   =   new RadTextBox();
                ((RadTextBox)c).Text                =   desc.ShortVal;
                ((RadTextBox)c).Width               =   TextWidth;
                if ( TextLen > 0 )
                    ((RadTextBox)c).MaxLength       =   TextLen;
                break;
            }
            c.ID                                    =   CtlID;
            // Insert Control in local list for reset or update
            EditControls.Add(fldName,c);
            c2.Controls.Add(c);
            if ( c is RadTextBox )
            {
                RadSpell spellChecker               =   new RadSpell();
                spellChecker.ID                     =   string.Format("RadSpell{0}",fldName);
                c2.Controls.Add(spellChecker);
                spellChecker.ControlToCheck         =   c.ClientID;
                spellChecker.ButtonText             =   LocalizeHelper.Localize("SPELL_CHECK","Spell Check");
                SpellCheckers.Add(c.ClientID,spellChecker);
            }
            rw.Cells.Add(c1);
            if ( !oneCol )
                rw.Cells.Add(c2);
            tb.Rows.Add(rw);
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateRow END isEditor: {0}, added control for: '{1}'", isEditor, desc.Fieldname),CrmFieldLocTrace.Sw.Info);
            return isEditor;
        }
        
        /// <summary>
		/// Create all requested fields and place them in the RadTabStrip
		/// </summary>
		void CreateFields(Guid CrmId)
		{
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields BEG CrmId: {0}",CrmId),CrmFieldLocTrace.Sw.Info);
            string entityName                       =   Settings[LStr.CrmFieldLocalizerEntity].Value;
            int nbTabs                              =   Settings[LStr.CrmFieldLocalizerNbTabs].ToInt();
			// Create the column set which indicates the fields to be retrieved.
            string AttrVal                          =   Settings[LStr.CrmFieldLocalizerFields].Value;
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields entityName: {0}, NbTabs: {1}, Fields: {2}",entityName,nbTabs,AttrVal ),CrmFieldLocTrace.Sw.Info);
            if ( string.IsNullOrEmpty(AttrVal) )
                return;
            string[] ValTb                          =   AttrVal.Split(new char[]{';'},StringSplitOptions.RemoveEmptyEntries);
            // Retrieve Crm Object and read DB values
            SqlDataReader dr                        =   null;
            try
            {
                currentDyn                          =    new DynEntity(Wrapper,entityName,CrmId);
                if ( !currentDyn.Retrieve() )
                {
                    if ( CrmFieldLocTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields NOT FOUND entityName: {0}, CrmId: {1}",entityName,CrmId),CrmFieldLocTrace.Sw.Info);
                }
                // Get Definitions from desc
                Vals                                =    new CRMLocalizer(entityName).Vals;
                int nbTb                            =   0;
                int nbMemo                          =   0;
                // Recover the CRM values as default values for fields
                foreach ( CRMFieldDescListKey key in Vals.Keys )
                {
                    CRMLocFieldDesc desc            =   Vals[key];
                    if ( currentDyn.ContainsKey(key.Fieldname) )
                    {
                        if ( CrmFieldLocTrace.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields setting from StringPropertyValue entityName: {0}, fldName: {1}",entityName,key.Fieldname),CrmFieldLocTrace.Sw.Info);
                        // Beware don't call directly StrinProperty to avoid default translator
                        string val                  =   Wrapper.StringPropertyValue(key.Fieldname,currentDyn.dicProperty);

                        if ( !string.IsNullOrEmpty(val) )
                        {
                            if ( desc.FieldType == AttributeInternalType.Memo )
                                desc.LongVal        =   val;
                            else
                                desc.ShortVal       =   val;
                        }
                    }
                    if ( desc.FieldType == AttributeInternalType.Memo )
                            nbMemo++;
                    else    nbTb++;
                }
                int nbTbByTab                           =   0;
                if ( nbTb != 0 )
                    nbTbByTab                           =   (nbTabs > nbTb) ? (nbTabs / nbTb): 1;
                // Get existing values
                dr                                      =   fDB.GetFieldLocalizerGlobalizedByEntity(entityName,CrmId);
                int i                                   =   0;
                while ( dr.Read() )
                {
                    int FieldId                         =   (int)dr["FieldId"];
                    string ShortValue                   =   (dr["ShortValue"] == DBNull.Value) ? string.Empty:(string)dr["ShortValue"];
                    string LongValue                    =   (dr["LongValue"] == DBNull.Value) ? string.Empty:(string)dr["LongValue"];

                    string strschemaName                =   (string)dr["Fieldname"];
                    CRMFieldDescListKey key             =   new CRMFieldDescListKey(PortalID,entityName,strschemaName);
                    CRMLocFieldDesc desc                =   Vals[key];
                    desc.ShortVal                       =   ShortValue;
                    desc.LongVal                        =   LongValue;
                    desc.Exist                          =   true;
                    if ( CrmFieldLocTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields found i: {0}, strschemaName: '{1}'", i, strschemaName),CrmFieldLocTrace.Sw.Info);
                    i++;
                }
                if ( dr != null ) 
                    dr.Close();
                // Build the display
                // To keep order we must use this array
                i                                       =   0;
                //string ToolProviderID                   =   string.Empty;
                List<RadEditor> EdLst                   =   new List<RadEditor>();
                if ( !NoTabs )
                {
                    Control tabPanelGroup           =   new HtmlGenericControl(StStr.Div);
                    ((HtmlGenericControl)tabPanelGroup).Attributes.Add("class", "LocalizerGroup");
                    ((HtmlGenericControl)tabPanelGroup).Style.Add( HtmlTextWriterStyle.Display, "block");
                    tabPanelGroup.ID                =   string.Format("{0}_tpg1",ClientID);
                    Control TabStripContainer       =   null;
                    Control MultiPageContainer      =   null;
                    
                    Table tb0                       =   new Table();
                    tb0.CellPadding                 =   0;
                    tb0.CellSpacing                 =   0;
                    tb0.BorderWidth                 =   0;
                    if ( SettingsTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields Table IsVertical: {0}", IsVertical),SettingsTraceSwitch.Sw.Info);
                    tb0.ID                          =   string.Format("{0}_TbVert",ClientID);
                    TableRow rw                     =   new TableRow();
                    TableCell cel                   =   new TableCell();
                    // if Vertical we put the TabStrip and MultiPage in the same cell
                    if ( IsVertical )
                    {
                        cel.Width                   =   new Unit(100,UnitType.Percentage);
                        cel.VerticalAlign           =   VerticalAlign.Top;
                        rw.Cells.Add(cel);
                        TabStripContainer           =   cel;
                        MultiPageContainer          =   cel;
                        tb0.Rows.Add(rw);
                    }
                    // When horiz we create 2 separate rows to put tabstrip on top of multipage
                    else
                    {
                        cel.Width                   =   new Unit(100,UnitType.Percentage);
                        cel.VerticalAlign           =   VerticalAlign.Top;
                        rw.Cells.Add(cel);
                        TabStripContainer           =   cel;
                        tb0.Rows.Add(rw);
                        rw                          =   new TableRow();
                        cel                         =   new TableCell();
                        cel.Width                   =   new Unit(100,UnitType.Percentage);
                        cel.VerticalAlign           =   VerticalAlign.Top;
                        rw.Cells.Add(cel);
                        MultiPageContainer          =   cel;
                        tb0.Rows.Add(rw);
                    }
                    //  We create the TabStrip that will contain the dynamics tabs
                    RadTabStrip tabStrip            =   new RadTabStrip();
                    StripMultiPages.Add(tabStrip);
                    if ( IsVertical )
                    {
                        tabStrip.Style.Add("float", "left");
                    }
                    tabStrip.SelectedIndex          =   0;
			        tabStrip.AutoPostBack           =   false;
                    tabStrip.CausesValidation       =   false;
			        tabStrip.Align                  =   Align;
			        tabStrip.Orientation            =   Orientation;
                    if ( SettingsTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields RadTabStrip created Align: {0}, Orientation: {1}",
                            tabStrip.Align,tabStrip.Orientation),SettingsTraceSwitch.Sw.Info);
                    TabStripContainer.Controls.Add(tabStrip);

                    // Now the related Multipage
                    RadMultiPage RMP                =   new RadMultiPage();
                    StripMultiPages.Add(RMP);
                    RMP.ID                          =   string.Format("{0}_RadMultiPage1",ClientID);
                    // we link them by the MP clienID (see telerik)
                    tabStrip.MultiPageID            =   RMP.ClientID;
                    RMP.SelectedIndex               =   tabStrip.SelectedIndex;
                    MultiPageContainer.Controls.Add(RMP);

                    // Then we fill the Multipage with RadPageViews
                    RadPageView tabPanel            =   null;

                    // Tabs are inserted dynamically in the TabStrip
                    RadTab tabDefault               =   null;
                    // this table will contain the setting items for this pageview
                    Table _tbl                      =   null;

                    // Seetings items are ordered by group in the collection SettingsOrder
                    // so we go through the collection and for each new group, we add a RadTab and a PagView, settings items will be added in the RadPageView
                    // until we change group
                    bool newTab                     =   true;
                    int TbCnt                        =   0;
                    foreach ( string fldName in ValTb )
                    {
                        CRMFieldDescListKey key             =   new CRMFieldDescListKey(PortalID,entityName,fldName);
                        CRMLocFieldDesc desc                =   Vals[key];
                        desc.DisplayName                    =   Wrapper.Util.ExtractAttributeDisplayName(entityName,fldName);
                        if ( !desc.Exist )
                        {
                            if ( desc.FieldType == AttributeInternalType.Memo )
                                    desc.LongVal            =   currentDyn.StringPropertyValue(fldName);
                            else    desc.ShortVal           =   currentDyn.StringPropertyValue(fldName);
                        }
                        if ( newTab )
                        {
                            newTab                          =   false;
                            TbCnt                           =   0;
                            // storing previously built tabpanel
                            if (tabDefault != null ) // add built fieldset
                            {
                                tabStrip.Tabs.Add(tabDefault);
                                tabPanel.Controls.Add(_tbl);
                                RMP.PageViews.Add(tabPanel);
                                if ( SettingsTraceSwitch.Sw.TraceVerbose )
                                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields added TabStrip: {0}", tabDefault.Text),SettingsTraceSwitch.Sw.Info);
                            }
                            // start a new Tab
                            tabDefault          =   new RadTab();
                            if ( desc.FieldType == AttributeInternalType.Memo )
                                    tabDefault.Text     =   desc.DisplayName;
                            else    tabDefault.Text     =   string.Format("Tab {0}",tabStrip.Tabs.Count);
                            // new content
                            tabPanel            =   new RadPageView();
                            tabPanel.ID         =   string.Format("PgV_{0}",tabStrip.Tabs.Count);
                            if ( !IsVertical )
                                tabPanel.Width  =   new Unit("100%");

                            // start a new table
                            _tbl                =   new Table();
                            _tbl.CellPadding    =   0;
                            _tbl.CellSpacing    =   0;
                            _tbl.CssClass       =   "FieldLocTable";
                            _tbl.Style.Add(HtmlTextWriterStyle.Width, "100%");
                            _tbl.Style.Add("table-layout", "fixed"); // Telerik Bug 2009.2.311
                        }
                        if ( CreateRow(desc,fldName,_tbl,EdLst,NoTabs) )
                            newTab = true;
                        else
                        {
                            TbCnt++;
                            if ( TbCnt == nbTbByTab )
                                newTab = true;
                        }
                        if ( SettingsTraceSwitch.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CreateFields added FldName: {0}, newTab: {1}", fldName,newTab),SettingsTraceSwitch.Sw.Info);
                    }

                    // datas for last group
                    tabStrip.Tabs.Add(tabDefault);
                    tabPanel.Controls.Add(_tbl);
                    RMP.PageViews.Add(tabPanel);
                    tabPanelGroup.Controls.Add(tb0);
                    FieldsPlaceHolder.Controls.Add(tabPanelGroup);
                }
                else // NoTabs
                {
                    Table tb                                =    new Table();
                    tb.CssClass                             =   "FieldLocTable";

                    foreach ( string fldName in ValTb )
                    {
                        CRMFieldDescListKey key             =   new CRMFieldDescListKey(PortalID,entityName,fldName);
                        CRMLocFieldDesc desc                =   Vals[key];
                        desc.DisplayName                    =   Wrapper.Util.ExtractAttributeDisplayName(entityName,fldName);
                        if ( !desc.Exist )
                        {
                            if ( desc.FieldType == AttributeInternalType.Memo )
                                    desc.LongVal            =   currentDyn.StringPropertyValue(fldName);
                            else    desc.ShortVal           =   currentDyn.StringPropertyValue(fldName);
                        }
                        CreateRow(desc,fldName,tb,EdLst,NoTabs);
                        i++;
                    }
                    // Add it to paceholder
                    FieldsPlaceHolder.Controls.Add(tb);
                }
                /* BUG with telerik: no spellchecker when ToolProviderID used
                bool first                      =   true;
                foreach ( RadEditor e in EdLst )
                {
                    if ( first )
                    {
                        first           =   false;
                        ToolProviderID  =   e.ClientID;
                    }
                    else
                        e.ToolProviderID = ToolProviderID;
                }*/

            }
            catch (Exception ex)
            {
                if ( ModuleTraceSwitch.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmFieldLocalizer CreateFields ex: {0}",ex),ModuleTraceSwitch.Sw.Info);
                throw;
            }
            finally
            {
                if ( dr != null ) 
                    dr.Close();
            }
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer CreateFields END.",CrmFieldLocTrace.Sw.Info);
		}

        #endregion Main methods

        #region Buttons event handlers

        void ResetBtn_Click(object sender,ImageClickEventArgs e)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer ResetBtn_Click BEG.",CrmFieldLocTrace.Sw.Info);
            foreach(Control c in EditControls.Values)
                if ( c is RadEditor )
                        ((RadEditor)c).Content  =   string.Empty;
                else    ((RadTextBox)c).Text    =   string.Empty;
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer ResetBtn_Click END.",CrmFieldLocTrace.Sw.Info);
        }

        /// <summary>
        /// Update Addon Nice DB with new values and update Crm when defaultlanguage
        /// </summary>
        void CrmFieldLocalizer_ADNUpdateModule(object sender,ModuleEventArgs e)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer CrmFieldLocalizer_ADNUpdateModule BEG.",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);

            string entityName                   =   Settings[LStr.CrmFieldLocalizerEntity].Value;
            bool updateEntity                   =   ( portalSettings.PortalDefLCID == portalSettings.PortalCurrentNeutralLCID );
            DynEntity currentDyn                =    new DynEntity(Wrapper,entityName,EntityID);
            try
            {
                foreach ( string k in EditControls.Keys )
                {
                    CRMFieldDescListKey key     =   new CRMFieldDescListKey(PortalID,entityName,k);
                    CRMLocFieldDesc desc        =   Vals[key];
                    Control c                   =   EditControls[k];
                    string val                  =   string.Empty;
                    if ( c is RadTextBox )
                    {
                        val                     =   ((RadTextBox)c).Text;
                        fDB.UpdateFieldLocalizerGlobalized(entityName,EntityID,desc.FieldId,val,string.Empty);
                    }
                    else    
                    {
                        val                     =   ((RadEditor)c).Content;
                        fDB.UpdateFieldLocalizerGlobalized(entityName,EntityID,desc.FieldId,string.Empty,val);
                    }
                    if ( CrmFieldLocTrace.Sw.TraceVerbose)
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmFieldLocalizer CrmFieldLocalizer_ADNUpdateModule key: {0}, FieldId: {1}, val: '{2}'.",
                                    key,desc.FieldId,val),CrmFieldLocTrace.Sw.Info);
                    if ( updateEntity )
                        currentDyn.AddStringProperty(desc.Fieldname,val);
                }
                // Try to update CRM associated fields if default language
                if ( updateEntity )
                {
                    if ( CrmFieldLocTrace.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmLocalizerManager CrmFieldLocalizer_ADNUpdateModule updating CRM entityName: {0}, EntityID: {1}",entityName,EntityID),CrmFieldLocTrace.Sw.Info);
                    currentDyn.Update();
                }

            }
            catch (Exception ex)
            {
                if ( ModuleTraceSwitch.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmFieldLocalizer CrmFieldLocalizer_ADNUpdateModule ex: {0}",ex),ModuleTraceSwitch.Sw.Info);
                throw;
            }

            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer CrmFieldLocalizer_ADNUpdateModule END.",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
        }

        #endregion Buttons event handlers

        protected override void OnPreRender(EventArgs e)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmLocalizerManager OnPreRender BEG CRM GoogleTranslate: {0}, IsPostBack: {1}, IsInAsyncPostBack: {2}",GoogleTranslate,IsPostBack,IsInAsyncPostBack),CrmFieldLocTrace.Sw.Info);
            if ( GoogleTranslate && !IsInAsyncPostBack )
            {
                string gPath    =   "http://www.google.com/jsapi";
                ((ADNPage)Page).RegisterADNClientScriptInclude("GoggleAPI", gPath);
                gPath           =   Path.ToAbsolute(Config.PortalScriptsPath + "/GoggleTranslator.js");
                ((ADNPage)Page).RegisterADNClientScriptInclude("GoggleTranslator", gPath);
            }
            base.OnPreRender(e);
            if ( CrmFieldLocTrace.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmLocalizerManager OnPreRender END.",CrmFieldLocTrace.Sw.Info);
        }


        #region Std Overrides

		public override void Page_PreInit(object sender, EventArgs e)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer Page_PreInit BEG.",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
            base.Page_PreInit(sender, e);
            string strcult              =   LocalizeHelper.GetCurrentNeutralCultureName();
            updateBtn.SkinID            =   "Update_" + strcult;
            ResetBtn.SkinID             =   "Reset_" + strcult;

            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer Page_PreInit END.",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
		}
		

        override protected void OnInit(EventArgs e)
        {
            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer OnInit BEG.",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
            InitializeComponent();
            base.OnInit(e);
            if ( CrmFieldLocTrace.Sw.TraceVerbose || ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmFieldLocalizer OnInit END.",(CrmFieldLocTrace.Sw.TraceVerbose) ? CrmFieldLocTrace.Sw.Info:ModuleTraceSwitch.Sw.Info);
        }
 

        private void InitializeComponent()
        {
            Load                        +=  new System.EventHandler(this.Page_Load);
            if ( IsUnderCRM && !IsInEntityCreationMode )
            {
                ADNUpdateModule         +=  new PortalModuleEventHandler(CrmFieldLocalizer_ADNUpdateModule);
                ResetBtn.Click          +=  new ImageClickEventHandler(ResetBtn_Click);
                CreateFields(EntityID);
            }
            else 
            {
                updateBtn.Enabled       =   false;
                ResetBtn.Enabled        =   false;
            }
        }

        #endregion
        
    }
}